package dystrybucja;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import bazy.Baza;

import wzorce.*;
import transport.*;

/*
 * Kiedy posprzatac ten bajzel???
 * tzn kiedy usuwa sie rezerwacje z mapy
 * byc moze po odjezie czyly trzeba usuwac rezerwacje po fakcie dokonanym?
 */


/*
 * ACHTUNG dodac tutaj pobieranie rezerwacji z jakiegos pliku
 */
public class ManagerRezerwacji implements Obserwator {
	
	private static ManagerRezerwacji manager;

		private void closeAll(Connection c, Statement s,ResultSet r, PreparedStatement p){
			try {
				if(c != null)
					c.close();
				if(s != null)
					s.close();
				if(r != null)
					r.close();
				if( p != null)
					p.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}

	/**
	 * 
	 * @param pesel Pesel osoby ktory dokonal rezerwacji
	 * @return Tablice rezerwacji lub null jezeli brak rezerwacji w bazie
	 */
	public Rezerwacja[] zwrocRezerwacje(long pesel) {
		Rezerwacja[] tablica = null;
		
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		try {
			conn = Baza.polacz("dworzec");
			st = conn.createStatement();
			
			String sql = "SELECT * FROM rezerwacje WHERE pesel = " + pesel;
		    rs = st.executeQuery(sql);
			
			if(rs.last()){
				int i = 0;
				int len = rs.getRow();
				rs.beforeFirst();
				tablica = new Rezerwacja[len];
				while(rs.next()){
					/*
					 * 1 - id , 2 - pesel , 3 - id polaczenia ,  4 - godzina odjazdu
					 * 5 - ilosc biletow,  6 - naleznosc do zalplaty
					 */
					tablica[i] = Rezerwacja.odtworzRezerwacje(rs.getInt(1), rs.getLong(2)
							, rs.getInt(3), rs.getDate(4)
							, rs.getInt(5), rs.getDouble(6));
					i++;
				}
			}
		} catch(SQLException e) {
			e.printStackTrace();
		}finally{
			closeAll(conn, st, rs,null);
		}
		
		return tablica;
		
	}

	/**
	 * 
	 * @param rezerwacja Rezerwacja do usuniecia
	 * @return True jezeli sie udalo , false jezeli nie
	 */
	public boolean usunRezerwacje(Rezerwacja rezerwacja) {
		Connection conn = null;
		Statement st = null;
		try {
			conn = Baza.polacz("dworzec");
			st = conn.createStatement();
			
			String sql = "DELETE  FROM rezerwacje WHERE id = " + rezerwacja.idRezerwacji;
		    int val  = st.executeUpdate(sql);
		    if(val != 0)
		    	return true;
		
		} catch(SQLException e) {
			e.printStackTrace();
		}finally{
			closeAll(conn, st, null,null);
		}
		return false;
	}
	
	/**
	 * 
	 * @param rezerwacja rezerwacja do zapisanie w bazie
	 * @return True jezeli sie udalo, false w przeciwnym wypadku
	 */
	public boolean zatwierdzRezerwacje(Rezerwacja rezerwacja) {
		Connection conn = null;
		Statement st = null;
		PreparedStatement ps = null;
		try {
			String sql = "INSERT INTO rezerwacje VALUES(?,?,?,?,?,?)";
			conn = Baza.polacz("dworzec");
			ps = conn.prepareStatement(sql);
			ps.setInt(1, rezerwacja.idRezerwacji);
			ps.setLong(2, rezerwacja.pesel);
			ps.setInt(3, rezerwacja.idPolaczenia);
			ps.setDate(4, new java.sql.Date(rezerwacja.odjazd.getTime()));
			ps.setInt(5, rezerwacja.iloscBiletow);
			ps.setDouble(6, rezerwacja.doZaplaty);
			
		    int val  = ps.executeUpdate();
		    if(val != 0){
		    	return true;
		    }
		    ps.close();
		} catch(SQLException e) {
			e.printStackTrace();
			return false;
		}finally{
			closeAll(conn, st, null,ps);
		}
		return false;
	}
	
	public String getCel(int id){
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		String trasa = null;
		String sql = "SELECT trasa from polaczenia where id = " +  id;
		try {
			conn = Baza.polacz("dworzec");
			st = conn.createStatement();
			rs = st.executeQuery(sql);
		if(rs.next())
			trasa = rs.getString(1);
		} catch(SQLException e) {
			e.printStackTrace();
		}finally{
			closeAll(conn, st, rs,null);
		}
		return trasa;
	}
	
	
	public int getMax(){
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		int val = 0;
		String sql = "SELECT MAX(id) from rezerwacje";
		try {
			conn = Baza.polacz("dworzec");
			st = conn.createStatement();
			rs = st.executeQuery(sql);
		if(rs.next())
			val = rs.getInt(1);
		} catch(SQLException e) {
			e.printStackTrace();
		}finally{
			closeAll(conn, st, rs,null);
		}
		return val;
	}
	public static ManagerRezerwacji manager(){
		if(manager == null)
			manager = new ManagerRezerwacji();
		return manager;
	}

	@Override
	/**
	 * @param Lista polaczen na ktore trzeba zwolnic rezerwacje
	 */
	public void aktualizacja(ArrayList<Polaczenie> polaczenia) {
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		String sql;
		try {
			conn = Baza.polacz("dworzec");
			st = conn.createStatement();
			for(Polaczenie pol : polaczenia){
				sql = "SELECT * FROM rezerwacje WHERE id_polaczenie = " + pol.getId();
				rs = st.executeQuery(sql);
				while(rs.next())
					rs.deleteRow();
			}
		} catch(SQLException e) {
			e.printStackTrace();
		}finally{
			closeAll(conn, st, rs,null);
		}
		
	}
	/**
	 * 
	 * @param id Id polaczenia skojarzone z przewoznikiem
	 * @return Przewoznika albo null
	 */
	public Przewoznik pobierzPrzewoznika(int id){
		Connection conn = null;
		Statement st = null;
		ResultSet rs = null;
		Przewoznik prze = new Przewoznik("",0,0,0,0);
		String sql = "SELECT pz.nazwa,pz.studenci,pz.emeryci,pz.kombatanci,pz.inwalidzi FROM polaczenia pol join przewoznicy_znizki pz " +
				"WHERE pol.id_przewoznika = pz.id AND pol.id = " +  id;
		try {
			conn = Baza.polacz("dworzec");
			st = conn.createStatement();
			rs = st.executeQuery(sql);
		if(rs.next())
			prze = new Przewoznik(rs.getString(1),rs.getDouble(2),rs.getDouble(3),rs.getDouble(4),rs.getDouble(5));
		
		} catch(SQLException e) {
			e.printStackTrace();
		}finally{
			closeAll(conn, st, rs,null);
		}
		
		return prze;
	}

}
